/**
 * File: SequenceWriteProcessor.java
 * Created by: mhaimel
 * Created on: 22 Jul 2009
 * CVS:  $Id: SequenceWriteProcessor.java,v 1.2 2009/10/09 15:14:58 mhaimel Exp $
 */
package uk.ac.ebi.curtain.processor.writer.impl;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import uk.ac.ebi.curtain.controller.loader.impl.ReadsWriteBean;
import uk.ac.ebi.curtain.controller.velvet.VelvetInputBean;
import uk.ac.ebi.curtain.util.impl.MultiFileFastqWriter;
import uk.ac.ebi.curtain.utils.CurtainUncheckedException;
import uk.ac.ebi.curtain.utils.data.ReadType;
import uk.ac.ebi.curtain.utils.file.FileInfo;
import uk.ac.ebi.curtain.utils.io.impl.FileIO;

/**
 * @author mhaimel
 *
 */
public class SequenceWriteProcessor extends AbstractSequenceProcessor<ReadsWriteBean, VelvetInputBean> {

	/**
	 * {@inheritDoc}
	 */
	@Override
	protected VelvetInputBean buildReturnObject() {
		VelvetInputBean input = new VelvetInputBean();
		input.setBaseDir(getInput().getBaseDir());
		input.getInputFiles().putAll(getOutFiles());
		return input;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void process() {
		getLog().debug("Start writing Sequences for " + getInput().getBaseDir());
		MultiFileFastqWriter out = null;
		try{
			out = getWriter();
			_prepareWriter(getInput().getBaseDir());
			
			for(FileInfo f : getOutFiles().keySet()){ // clear files
				if( !f.getReadType().equals(ReadType.Contig) 
						&& f.getFile().exists() 
						&& !f.getFile().delete()){
					throw new CurtainUncheckedException("Not able to delete file " + f);
				}
			}
			out.openWrite(true);
			_process();		
		} catch (IOException e) {
			throw new CurtainUncheckedException("Problems writing Reads to files",e);
		} finally{
			FileIO.closeQuietly(out);
		}
		getLog().debug("Finished write Sequences for " + getInput().getBaseDir());
	}

	private void _process() {
		List<Integer> fileIds = new ArrayList<Integer>();
		List<Long> posArr = new ArrayList<Long>();
		for(Long globPos : getInput().getReadPositions()){
			Integer fId = getFileIdFromPos(globPos);
			Long pos = translatePos(fId,globPos);
			fileIds.add(fId);
			posArr.add(pos);
		}
		getWriter().addReadBatch(
				fileIds.toArray(new Integer[0]),
				null, null, // this two values are not needed for this implementation 
				posArr.toArray(new Long[0]));
	}

	private Long translatePos(Integer id, Long globPos) {
		Long start = getContext().getGlobalFileIndex().getStartPosition(id);
		return globPos-start;
	}

	private Integer getFileIdFromPos(Long globPos) {
		return getContext().getGlobalFileIndex().getId(globPos);
	}

}
